﻿/*************************************************************************************
 * 工    具：  HK_TextureSetting
 * 
 * 描    述：  贴图批量化设置及压缩工具，可批处理图片的分辨率（调整为4的倍数），
 *            也可批量设置图片的压缩格式；
 *            目前只支持 Windows、WebGL、Android 目标平台；
 *            设置图片分辨率时，直接选择图片文件进行操作；
 *            设置压缩格式时，选择包含贴图的单一文件夹进行操作，
 *            工具只会压缩设置当前文件夹下的贴图；
 * 
 * 版    本：  V1.0
 * 作    者：  京产肠饭、王凯
 * 
 * 创    建：  2023/10/30  V1.0
 * 
 * 链    接：  https://gitee.com/JingChanChangFan/hk_-unity-tools
*************************************************************************************/

using System.IO;
using UnityEditor;
using UnityEngine;

namespace HKTools
{
    public enum Platform
    {
        Standalone,
        Android,
        WebGL
    }

    public class HK_TextureSetting : EditorWindow
    {
        static BuildTarget buildTarget;
        static Platform curPlatform;
        static TextureImporterFormat curTextureFormat = TextureImporterFormat.DXT1Crunched;

        [MenuItem("HKTools/Texture Settings (贴图设置工具)", priority = HK_MenuPriority.HK_TextureSetting)]
        static void Init()
        {
            HK_TextureSetting textureSetting = GetWindow<HK_TextureSetting>(false, "Texture Settings", true);
            textureSetting.Show();

            buildTarget = EditorUserBuildSettings.activeBuildTarget;

            switch (buildTarget)
            {
                case BuildTarget.StandaloneWindows:
                case BuildTarget.StandaloneWindows64:
                    curPlatform = Platform.Standalone;
                    curTextureFormat = TextureImporterFormat.DXT1Crunched;
                    break;
                case BuildTarget.Android:
                    curPlatform = Platform.Android;
                    curTextureFormat = TextureImporterFormat.ASTC_8x8;
                    break;
                case BuildTarget.WebGL:
                    curPlatform = Platform.WebGL;
                    curTextureFormat = TextureImporterFormat.DXT1Crunched;
                    break;
            }

            Debug.Log("当前目标平台为：" + curPlatform.ToString());
        }

        void OnGUI()
        {
            // 设置图片 分辨率
            GUILayout.Label("用于将分辨率不是4的倍数的UI图片，分辨率调整为最近似的4的倍数，便于压缩格式设置\r\n设置图片分辨率时，请直接选择图片文件!");

            GUILayout.Space(5);

            if (GUILayout.Button("设置分辨率为4的倍数", GUILayout.Width(200)))
            {
                SetTextureResolution();
            }

            GUILayout.Space(15);

            // 设置图片 压缩格式
            GUILayout.Label("设置图片压缩格式时，请选择单个包含贴图的文件夹!");

            GUILayout.Space(5);

            GUILayout.Label("设置格式：");
            curTextureFormat = (TextureImporterFormat)EditorGUILayout.EnumPopup(curTextureFormat, GUILayout.Width(200));

            GUILayout.Space(5);

            if (GUILayout.Button("设置贴图格式", GUILayout.Width(200)))
            {
                SetTextureFormat();
            }
        }

        void SetTextureResolution()
        {
            Object[] selectedObjects = Selection.objects;

            foreach (Object obj in selectedObjects)
            {
                string path = AssetDatabase.GetAssetPath(obj);
                if (string.IsNullOrEmpty(path))
                {
                    Debug.Log("Scene场景中的物体");
                    continue;
                }

                if (path.EndsWith(".png") || path.EndsWith(".jpg") ||
                      path.EndsWith(".tga") || path.EndsWith(".psd") ||
                      path.EndsWith(".PSD") || path.EndsWith(".exr") ||
                      path.EndsWith(".tif") || path.EndsWith(".PNG") ||
                      path.EndsWith(".JPG") || path.EndsWith(".jpeg"))
                {
                    Debug.Log("图片：" + path);

                    TextureImporter importer = AssetImporter.GetAtPath(path) as TextureImporter;
                    TextureImporterPlatformSettings setting = importer.GetPlatformTextureSettings(curPlatform.ToString());

                    int width, height;
                    importer.GetSourceTextureWidthAndHeight(out width, out height);

                    // 检查宽高是否为4的倍数，不是则进行裁剪
                    if (width % 4 != 0 || height % 4 != 0)
                    {
                        int newWidth = (width / 4) * 4; // 减去多余的像素以达到4的倍数
                        int newHeight = (height / 4) * 4;

                        string assetPath = Path.Combine(Directory.GetCurrentDirectory(), path);
                        Texture2D originalTexture = LoadTexture(assetPath);

                        if (originalTexture == null)
                        {
                            Debug.LogError("图片加载失败：" + path);
                            return;
                        }

                        // 创建新的裁剪后的Texture2D
                        Texture2D newTexture = new Texture2D(newWidth, newHeight);
                        Color[] pixels = originalTexture.GetPixels(0, 0, newWidth, newHeight);
                        newTexture.SetPixels(pixels);
                        newTexture.Apply();

                        // 保存新的Texture
                        byte[] bytes = newTexture.EncodeToPNG();

                        File.WriteAllBytes(assetPath, bytes);

                        // 释放原始Texture2D资源
                        DestroyImmediate(newTexture);

                        // 强制重新导入更新的贴图
                        AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate);

                        // 再次获取导入器以更新设置
                        importer = AssetImporter.GetAtPath(path) as TextureImporter;
                        Debug.LogWarning("图片：" + path + "\t Resolution:" + width + " * " + height + "\tTo Resolution:" + newWidth + " * " + newHeight);
                    }

                    setting.overridden = true;

                    importer.SetPlatformTextureSettings(setting);

                    AssetDatabase.ImportAsset(path);
                }
                else
                {
                    Debug.Log("不是图片");
                }
            }
        }

        void SetTextureFormat()
        {
            if (buildTarget != BuildTarget.StandaloneWindows64
                   && buildTarget != BuildTarget.StandaloneWindows
                   && buildTarget != BuildTarget.WebGL
                   && buildTarget != BuildTarget.Android)
            {
                Debug.LogError("该工具目前只支持 Windows、WebGL、Android 目标平台！");
                return;
            }

            // 如果选择的数量不对，则 return
            if (Selection.objects.Length == 0 || Selection.objects.Length >= 2)
            {
                Debug.LogError("请选择唯一的文件夹!");
                return;
            }

            // 如果选择的不是文件夹，则 return
            string selectPath = AssetDatabase.GetAssetPath(Selection.objects[0]);
            if (!Directory.Exists(selectPath))
            {
                Debug.LogError("选择的不是文件夹!");
                return;
            }

            string[] guidArray = Selection.assetGUIDs;
            foreach (string guid in guidArray)
            {
                string selectFolder = AssetDatabase.GUIDToAssetPath(guid);
                DirectoryInfo root = new DirectoryInfo(selectFolder);

                FileInfo[] fileArray = root.GetFiles();
                foreach (FileInfo file in fileArray)
                {
                    if (file.FullName.EndsWith(".png") || file.FullName.EndsWith(".jpg") ||
                        file.FullName.EndsWith(".tga") || file.FullName.EndsWith(".psd") ||
                        file.FullName.EndsWith(".PSD") || file.FullName.EndsWith(".exr") ||
                        file.FullName.EndsWith(".tif") || file.FullName.EndsWith(".PNG") ||
                        file.FullName.EndsWith(".JPG") || file.FullName.EndsWith(".jpeg"))
                    {
                        string path = file.FullName.Replace('\\', '/').Replace(Application.dataPath.Replace("Assets", ""), "");


                        TextureImporter importer = AssetImporter.GetAtPath(path) as TextureImporter;
                        TextureImporterPlatformSettings setting = importer.GetPlatformTextureSettings(curPlatform.ToString());

                        // 如果是 法线贴图（NormalMap）
                        if (importer.textureType == TextureImporterType.NormalMap)
                        {
                            setting.format = MakeSureHaveAlpha(curTextureFormat);
                        }
                        // 如果是 默认贴图格式（Default）
                        else if (importer.textureType == TextureImporterType.Default)
                        {
                            // 如果有 Alpha 通道
                            if (importer.DoesSourceTextureHaveAlpha())
                            {
                                setting.format = MakeSureHaveAlpha(curTextureFormat);
                            }
                            else
                            {
                                setting.format = MakeSureRemoveAlpha(curTextureFormat);
                            }
                        }
                        // 如果是 UI贴图格式（Sprite）
                        else if (importer.textureType == TextureImporterType.Sprite)
                        {
                            // 如果有 Alpha 通道
                            if (importer.DoesSourceTextureHaveAlpha())
                            {
                                setting.format = MakeSureHaveAlpha(curTextureFormat);
                            }
                            else
                            {
                                setting.format = MakeSureRemoveAlpha(curTextureFormat);
                            }
                        }

                        setting.overridden = true;

                        importer.SetPlatformTextureSettings(setting);

                        int width, height;
                        importer.GetSourceTextureWidthAndHeight(out width, out height);

                        if (width % 4 != 0 || height % 4 != 0)
                        {
                            Debug.LogWarning("图片：" + path + " 分辨率非4的倍数，无法压缩");
                        }

                        AssetDatabase.ImportAsset(path);
                    }
                }
            }
        }

        // 确保有alpha通道
        TextureImporterFormat MakeSureHaveAlpha(TextureImporterFormat format)
        {
            if (format == TextureImporterFormat.DXT1Crunched)
                format = TextureImporterFormat.DXT5Crunched;

            return format;
        }

        // 确保没有alpha通道
        TextureImporterFormat MakeSureRemoveAlpha(TextureImporterFormat format)
        {
            if (format == TextureImporterFormat.DXT5Crunched)
                format = TextureImporterFormat.DXT1Crunched;

            return format;
        }

        // 加载图片为Texture2D
        Texture2D LoadTexture(string filePath)
        {
            Texture2D tex = null;
            byte[] fileData;

            if (File.Exists(filePath))
            {
                fileData = File.ReadAllBytes(filePath);
                tex = new Texture2D(2, 2);
                if (!tex.LoadImage(fileData)) // 使用LoadImage将图片的byte加载到Texture2D上
                {
                    Debug.LogError("图片加载失败：" + filePath);
                    tex = null;
                }
            }
            Debug.Log("图片加载成功");
            return tex;
        }
    }
}